home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / sdi / input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-08  |  7.3 KB  |  283 lines

  1. /************************************  input.c  *************************/
  2. #include "sdi.h"
  3. #include <sunwindow/notify.h>
  4. #include <fcntl.h>
  5. #include <sys/ioctl.h>
  6. #include <stdio.h>
  7. #include <errno.h>
  8.  
  9. /*
  10.  * Copyright 1987 by Mark Weiser.
  11.  * Permission to reproduce and use in any manner whatsoever on Suns is granted
  12.  * so long as this copyright and other identifying marks of authorship
  13.  * in the code and the game remain intact and visible.  Use of this code
  14.  * in other products is reserved to me--I'm working on Mac and IBM versions.
  15.  */
  16.  
  17. /*
  18.  * interrupt handling is here, including mousing, resizing, etc.
  19.  */
  20.  
  21. extern Panel launchpanel;
  22.  
  23. Notify_value update_icon();
  24.  
  25. void
  26. canvas_resize_proc(canvas, width, height)
  27. Canvas canvas;
  28. int width, height;
  29. {
  30.     void new_game_proc();
  31.     void draw_background();
  32.     struct pixwin *pw, *newpw;;
  33.  
  34.     if (canvas == citycanvas || canvas == launchcanvas) {
  35.         max_x = width-(2*FIELD_MARGIN)-4;
  36.         max_y = height-(2*FIELD_MARGIN)-4;
  37.         newpw = pw_region(canvas_pixwin(canvas), FIELD_MARGIN, FIELD_MARGIN,
  38.             max_x, max_y);
  39.     }
  40.     /*
  41.      * Can't do the pw_closes here, because lurking missiles may still
  42.      * be depending on them.  So never do them--how many resizes are
  43.      * there per game, anyway?
  44.      */
  45.     if (canvas == citycanvas) {
  46.         /* pw_close(citypw); */
  47.         citypw = newpw;
  48.         num_cities = 0;
  49.         init_cities();
  50.     } else if (canvas == launchcanvas) {
  51.         /* pw_close(launchpw); */
  52.         launchpw = newpw;
  53.     }
  54. }
  55. int running_icon_pictures = 0;
  56. static int old_frame_width = -1, old_frame_height = -1;
  57.  
  58. /*
  59.  * This routine gets notifications even before SunView does.  Almost the first
  60.  * thing it does is all 'notify_next_event_func', which lets SunView do
  61.  * its work.  Resizes, opens, and closes are handled here.
  62.  */
  63. Notify_value
  64. synch_event_proc(frame, event, arg, type)
  65. Frame frame;
  66. Event *event;
  67. Notify_arg arg;
  68. Notify_event_type type;
  69. {
  70.     int new_game;
  71.     int closed;
  72.     static int oldclosed = 0;
  73.     Notify_value value;
  74.  
  75.     /* send on the notification */
  76.     value = notify_next_event_func(frame, event, arg, type);
  77.  
  78.     /* start post-processing */
  79.     closed = (int) window_get(frame, FRAME_CLOSED);
  80.     if (frame == controlframe) {
  81.         if ( closed && !oldclosed) {
  82.             /* not many events come in while closed,
  83.              * so if we are closed, we are probably
  84.              * just now closing.  Close everyone.
  85.              */
  86.             window_set(cityframe, WIN_SHOW, FALSE,
  87.                 0);
  88.             window_set(launchframe, WIN_SHOW, FALSE,
  89.                 0);
  90.             if (running)
  91.                 suspend_proc();
  92.             if (!running_icon_pictures) {
  93.                 /* start the icon stuff */
  94.                 running_icon_pictures = 1;
  95.                 do_with_delay(update_icon, 0, 1);
  96.             }
  97.         } else if (!closed) {
  98.             /* opening control frame, and so show everybody */
  99.             if (! window_get(cityframe, WIN_SHOW))
  100.                 window_set(cityframe, WIN_SHOW, TRUE, 0);
  101.             if (! window_get(launchframe, WIN_SHOW))
  102.                 window_set(launchframe, WIN_SHOW, TRUE, 0);
  103.             if (running_icon_pictures) {
  104.                 /* stop the icon stuff */
  105.                 running_icon_pictures = 0;
  106.             }
  107.         }
  108.         oldclosed = closed;
  109.     } 
  110.     /* Check for a resize request.
  111.        If either playing field is resized they both are.
  112.      */
  113.     if (event_id(event) == WIN_RESIZE && 
  114.         (frame == cityframe || frame == launchframe)) {
  115.         int w = (int)window_get(frame, WIN_WIDTH);
  116.         int h = (int)window_get(frame, WIN_HEIGHT);
  117.         if ((old_frame_height == h && old_frame_width == w))
  118.             goto done;
  119.         if ((old_frame_height == -1 && old_frame_width == -1)
  120.             || (!running)
  121.             || popup_warning(frame, event, "Ok to restart game?")) {
  122.                 new_game = 1;
  123.                 old_frame_height = h;
  124.                 old_frame_width = w;
  125.         } else {
  126.             new_game = 0;
  127.             h = old_frame_height;
  128.             w = old_frame_width;
  129.         }
  130.         /* can't get too small, or else things start to break. */
  131.         h = max(MINWIN, h);
  132.         w = max(MINWIN, w);
  133.         window_set(cityframe, WIN_WIDTH, w, WIN_HEIGHT, h, 0);
  134.         window_set(launchframe, WIN_WIDTH, w, WIN_HEIGHT, h, 0);
  135.         if (new_game)    {
  136.             /*
  137.              * If resizing, it must be time to start a new game.
  138.              */
  139.             do_with_delay(new_game_proc, 0, 100000);
  140.         }
  141.     }
  142. done:
  143.     return value;
  144. }
  145.  
  146. /*
  147.  * Handle mousing.
  148.  */
  149. #define PINX(x) (max(0,min(max_x,x)))
  150. #define PINY(y) (max(0,min(max_y,y)))
  151.  
  152. static int rock_x = -1, rock_y;
  153. Event rock_down_event;
  154.  
  155. void
  156. main_event_proc(window, event, arg)
  157. Window window;
  158. Event *event;
  159. caddr_t arg;
  160. {
  161.     extern Panel_item rock_item;
  162.     int times_around, offset, i;
  163.     int id = event_id(event);
  164.     int inc, left;
  165.     Pixwin *pw;
  166.  
  167.     /*
  168.      * The following totally silly call is a kludge to work-around
  169.      * a Sun bug which, if we *don't* refuse the input focus, loses the 
  170.      * middle-button down transition when we first are handed the input focus.
  171.      */
  172.     if (event_id(event) == KBD_REQUEST) {
  173.         window_refuse_kbd_focus(window);
  174.         return;
  175.     }
  176.  
  177.     if (! event_is_button(event)) return;
  178.     if (suspended) return;
  179.  
  180.     if (window == citycanvas) {
  181.         pw = citypw;
  182.     } else {
  183.         pw = launchpw;
  184.     }
  185.  
  186.     if (event_is_down(event)) {
  187.         if (!running) {
  188.             /* if not running, then try to start running. */
  189.             start_next_round();
  190.         } else {
  191.             switch(id) {
  192.             case MS_LEFT: {
  193.                 left = (int)panel_get_value(interceptor_item);
  194.                 if (left > 0) {
  195.                     if (event_meta_is_down(event)) {
  196.                         times_around = 2;
  197.                         offset = event_shift_is_down(event) ? -31 : -20;
  198.                     } else {
  199.                         times_around = 1;
  200.                         offset = 0;
  201.                     }
  202.                     for (i = 0; i < times_around; i += 1) {
  203.                         if (event_shift_is_down(event)) {
  204.                             start_blast(PINX(event_x(event)+offset), event_y(event), 0, 0, pw, bigblastcircles);
  205.                         } else {
  206.                             start_blast(PINX(event_x(event)+offset), event_y(event), 0, 0, pw, littleblastcircles);
  207.                         }
  208.                         offset = ABS(offset);
  209.                     }
  210.                     panel_set_value(interceptor_item, left-times_around);
  211.                     update_cursor();
  212.                 } else {
  213.                     need_a_bell = pw;
  214.                 }
  215.                 break;
  216.             } 
  217.             case MS_RIGHT: {
  218.                 left = (int)panel_get_value(laser_item);
  219.                 if (left > 0) {
  220.                     if (event_meta_is_down(event)) {
  221.                         times_around = 2;
  222.                         offset = event_shift_is_down(event) ? -100 : -64;
  223.                     } else {
  224.                         times_around = 1;
  225.                         offset = 0;
  226.                     }
  227.                     for (i = 0; i < times_around; i += 1) {
  228.                         if (event_shift_is_down(event)) {
  229.                             start_laser(PINX(event_x(event)+offset), event_y(event), 
  230.                                 pw, 3, 256);
  231.                         } else {
  232.                             start_laser(PINX(event_x(event)+offset), event_y(event), 
  233.                                 pw, 6, 128);
  234.                         }
  235.                     offset = ABS(offset);
  236.                     }
  237.                     panel_set_value(laser_item, left-times_around);
  238.                     update_cursor();
  239.                 } else {
  240.                     need_a_bell = pw;
  241.                 }
  242.                 break;
  243.             }
  244.             case MS_MIDDLE: {
  245.                 left = (int)panel_get_value(rock_item);
  246.                 if (left > 0) {
  247.                     rock_x = event_x(event);
  248.                     rock_y = event_y(event);
  249.                     rock_down_event = *event;
  250.                 } else {
  251.                     rock_x = -1;
  252.                     need_a_bell = pw;
  253.                 }
  254.             }} /* end of switch */
  255.         }
  256.     } else if (/* implicit: event_is_up(event) && */
  257.             running && id == MS_MIDDLE && rock_x != -1) {
  258.         /* throw some rocks */
  259.         if (event_meta_is_down(&rock_down_event)) {
  260.             times_around = 2;
  261.             offset = -20;
  262.         } else {
  263.             times_around = 1;
  264.             offset = 0;
  265.         }
  266.         for (i = 0; i < times_around; i += 1) {
  267.             if (event_shift_is_down(&rock_down_event)) {
  268.                 start_rocks(pw, rock_x, PINY(rock_y+offset),
  269.                     event_x(event), PINY(event_y(event)+offset), 
  270.                     3, bigrockcircles);
  271.             } else {
  272.                 start_rocks(pw, rock_x, PINY(rock_y+offset),
  273.                     event_x(event)+offset, PINY(event_y(event)+offset),
  274.                     5, littlerockcircles);
  275.             }
  276.             offset = ABS(offset);
  277.         }
  278.         rock_x = -1;
  279.         panel_set_value(rock_item, panel_get_value(rock_item)-times_around);
  280.         update_cursor();
  281.     }
  282. }
  283.